#include "Sock.h"

int Sock::Socket()
{
    int listensock = socket(AF_INET, SOCK_STREAM, 0);
    if (listensock < 0)
    {
        LOG_ERROR("sock create error");
        exit(0);
    }
    int opt = 1;

    setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));
    return listensock;
}

bool Sock::Bind(int sock, uint16_t port, std::string ip)
{

    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        LOG_ERROR("%d : %s", errno, strerror(errno));
        LOG_ERROR("sock bind error");
        close(sock);
        exit(1);
    }
    return true;
}

bool Sock::Listen(int sock)
{
    assert(sock >= 0);
    if (listen(sock, 6) < 0)
    {
        LOG_ERROR("sock listen error");
        exit(2);
    }
    return true;
}

int Sock::Accept(int sock, struct sockaddr_in *clientaddr)
{
    socklen_t len = sizeof(clientaddr);
    int clientsock = accept(sock, (struct sockaddr *)clientaddr, &len);
    return clientsock;
}

bool Sock::Connect(int sock, std::string serverip, uint16_t serverport)
{
    struct sockaddr_in serveraddr;
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(serverport);
    serveraddr.sin_addr.s_addr = inet_addr(serverip.c_str());
    if (connect(sock, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == 0)
    {
        LOG_ERROR("sock connect error");
        return false;
    }
    return true;
}